package ar.edu.unicen.exa.isistan.archassis.model;

import java.util.ArrayList;
import java.util.List;

import ar.edu.unicen.exa.isistan.archassis.ia.api.AIModuleFacade;
import ar.edu.unicen.exa.isistan.archassis.ia.api.EvalResult;
import ar.edu.unicen.exa.isistan.archassis.ia.api.db.JavaClass;
import ar.edu.unicen.exa.isistan.archassis.model.listeners.ICasesListener;
import ar.edu.unicen.exa.isistan.archassis.model.listeners.IClassesListener;
import ar.edu.unicen.exa.isistan.archassis.model.listeners.ISRCFolderClassesListener;
import ar.edu.unicen.exa.isistan.archassis.model.listeners.ISelectedCaseListener;
import ar.edu.unicen.exa.isistan.archassis.model.listeners.ISourceStrategyListener;
import ar.edu.unicen.exa.isistan.archassis.source.ISourceStrategy;

/**
 * Esta clase permite agregar o setear los listeners que escucharán los 
 * diferentes cambios sobre el estado de la aplicación.
 * 
 * Se pueden utilizar los siguientes listeners:
 * <ul>
 * 		<li>Cambió la lista de <i>Source Folders</i> disponibles, ver {@link #setSRCFolderClassesListener(ISRCFolderClassesListener)}</li>
 * 		<li>Cambió el <i>Source Folder</i> seleccionado, ver {@link #addClassesListener(IClassesListener)}</li>
 * 		<li>Cambió la lista de casos disponibles, ver {@link #setCasesListener(ICasesListener)}</li>
 * 		<li>Cambió el caso seleccionado, ver {@link #addSelectedCaseListener(ISelectedCaseListener)}</li>
 * </ul>
 * 
 * @author sebastianperruolo@gmail.com
 * @author sackiti@gmail.com
 *
 */
public class ModelManager {
	private static ModelManager instance = new ModelManager();
	private ModelManager() {}
	public static ModelManager getInstance() {
		return instance;
	}
	
	private List<IClassesListener> classesListener = new ArrayList<IClassesListener>();
	public void addClassesListener(IClassesListener listener) {
		this.classesListener.add(listener);
	}
	
	private List<JavaClass> classesList = null;
	public void setClassesList(List<JavaClass> classesList) {
		this.classesList = classesList;
		
		for (IClassesListener aClassesListener: classesListener) {
			aClassesListener.change(this.classesList);
		}
		
		EvalResult evalResult = null;
		if (this.classesList != null) {
			evalResult = AIModuleFacade.getInstance().evaluate(this.classesList);
		}
		ModelManager.getInstance().setCaseSelected(evalResult);
		//setCasesList(evalResultList);
	}
	
//	private ICasesListener casesListener = null;
//	public void setCasesListener(ICasesListener listener) {
//		this.casesListener = listener;
//	}
//	
//	private List<ListCasesResult> casesList = null;
//	public void setCasesList(List<ListCasesResult> list) {
//		this.casesList = list;
//		if (casesListener != null) {
//			casesListener.change(this.casesList);
//		}
//		setCaseSelected(null);
//	}
	
	private List<ISelectedCaseListener> selectedCaseListener = new ArrayList<ISelectedCaseListener>();
	public void addSelectedCaseListener(ISelectedCaseListener listener) {
		this.selectedCaseListener.add(listener);
	}
	
	private EvalResult evalResult = null;
	public void setCaseSelected(EvalResult evalResult) {
		this.evalResult = evalResult;
		for (ISelectedCaseListener aCaseListener: selectedCaseListener) {
			aCaseListener.change(this.evalResult);
		}
	}
	
//	private IRCSListener rcsListener = null;
//	public void setRCSListener(IRCSListener listener) {
//		this.rcsListener = listener;
//	}
	
//	private IRevisionControlSystem revisionControlSystem = null;
//	public void setRevisionControlSystem(IRevisionControlSystem rcs) {
//		this.revisionControlSystem = rcs;
//		if (rcsListener != null) {
//			rcsListener.changeRCS(this.revisionControlSystem);
//		}
//		setVersionFrom(null, false);
//		setVersionTo(null, false);
//		setCasesList(null);
//		setClassesList(null);
//	}
//	public IRevisionControlSystem getRevisionControlSystem() {
//		return this.revisionControlSystem; 
//	}
	
//	private IVersion versionFrom = null;
//	public IVersion getVersionFrom() {
//		return this.versionFrom;
//	}
//	public void setVersionFrom(IVersion v) {
//		setVersionFrom(v, true);
//	}
//	private void setVersionFrom(IVersion v, boolean propagate) {
//		this.versionFrom = v;
//		if (rcsListener != null) {
//			rcsListener.changeVersionFrom(this.versionFrom);
//		}
//		if (propagate) {
//			setCasesList(null);
//			setClassesList(null);
//		}
//	}
	
//	private IVersion versionTo = null;
//	public IVersion getVersionTo() {
//		return this.versionTo;
//	}
//	public void setVersionTo(IVersion v) {
//		setVersionTo(v, true);
//	}
//	private void setVersionTo(IVersion v, boolean propagate) {
//		this.versionTo = v;
//		if (rcsListener != null) {
//			rcsListener.changeVersionTo(this.versionTo);
//		}
//		if (propagate) {
//			setCasesList(null);
//			setClassesList(null);
//		}
//	}
	
	private ISourceStrategyListener ssListener = null;
	public void setSourceStrategyListener(ISourceStrategyListener listener) {
		this.ssListener = listener;
	}
	
	private ISourceStrategy sourceStrategy = null;
	public ISourceStrategy getSourceStrategy() {
		return sourceStrategy;
	}
	public void setSourceStrategy(ISourceStrategy ss) {
		this.sourceStrategy = ss;
		if (ssListener != null) {
			ssListener.change(this.sourceStrategy);
		}
	}


}
